"""自定义中间件，用于跟踪指标和其他横切关注点。

这个模块提供了中间件功能，用于监控和收集应用程序的HTTP请求指标，
包括请求计数、响应时间等关键性能指标。
"""

import time
from typing import Callable

from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import Response

from app.core.metrics import (
    http_requests_total,
    http_request_duration_seconds,
    db_connections,
)


class MetricsMiddleware(BaseHTTPMiddleware):
    """用于跟踪HTTP请求指标的中间件。

    该中间件负责收集和记录每个HTTP请求的关键指标，包括：
    - 请求总数，按方法、端点和状态码分类
    - 请求处理持续时间，用于性能监控
    """

    async def dispatch(self, request: Request, call_next: Callable) -> Response:
        """处理每个请求并收集相关指标。

        Args:
            request: 传入的HTTP请求
            call_next: 下一个中间件或路由处理器

        Returns:
            Response: 应用程序返回的响应

        该方法会测量请求处理时间，并记录请求计数和响应时间指标，
        用于监控应用程序的性能和健康状况。
        """
        # 记录请求开始时间
        start_time = time.time()

        try:
            # 处理请求并获取响应
            response = await call_next(request)
            status_code = response.status_code
        except Exception:
            # 如果发生异常，将状态码设为500（服务器内部错误）
            status_code = 500
            raise
        finally:
            # 计算请求处理持续时间
            duration = time.time() - start_time

            # 记录请求总数指标，按HTTP方法、端点和状态码分类
            http_requests_total.labels(method=request.method, endpoint=request.url.path, status=status_code).inc()

            # 记录请求持续时间指标，用于性能监控
            http_request_duration_seconds.labels(method=request.method, endpoint=request.url.path).observe(duration)

        return response
